package com.landmark;

import java.awt.EventQueue;
import java.io.*;
import java.util.Hashtable;
import javax.swing.JPanel;

public class Tagging extends JPanel {

    String strFolder = "";
    String strTagOutFileDepFolder = "";
    String strTagOutFilePath = "";
    String strRemPrefix = "";
    String strRemSuffix = "";
    Hashtable<String, String> htTypes = new Hashtable<String, String>();
    TypeConstants types = new TypeConstants();
    OptionConstants options = new OptionConstants();
//    BufferedWriter errorFile = null;

    /**
     * *
     *
     * @throws Exception
     */
    public void start() throws Exception {
        //BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
//        errorFile = new BufferedWriter(new FileWriter("./outputs/ErrorFile.txt"));
        String folderPath = strFolder;

        String tagOutFileDepFolder = strTagOutFileDepFolder;

        String[] dir = new java.io.File(folderPath).list();

        FileWriter bankFile = new FileWriter(folderPath + "/UM_Tag_Bank_IN.csv", true);

        java.util.Arrays.sort(dir);

        File tempFiles[] = new File(folderPath + "/temp").listFiles();
        int len1 = tempFiles.length;
        for (int i = 0; i < len1; i++) {
            File file = tempFiles[i];
            String name = file.getName();
            System.out.println(name);
//            errorFile.write(name + "\n");
            bankFile.append("\n\n");

            if (name.equals("CatstoAdd.csv")) {
                addCats2Bank(bankFile, file);
            }

            if (name.equals("ColorstoAdd.csv")) {
                addColors2Bank(bankFile, file);
            }

            if (name.equals("DescriptionWordstoAdd.csv")) {
                addDesc2Bank(bankFile, file);
            }

            if (name.equals("OptionstoAdd.csv")) {
                addOptions2Bank(bankFile, file);
            }
        }
        bankFile.close();
    }

    /**
     * *
     *
     * @param bankFile
     * @param file
     * @throws Exception
     */
    private void addCats2Bank(FileWriter bankFile, File file) throws Exception {
        try {
            BufferedReader reader = new BufferedReader(new FileReader(file));
            BufferedWriter writer = new BufferedWriter(bankFile);
            String line = null;
            int lineCount = 0;
            while ((line = reader.readLine()) != null) {
                //line = line.replaceAll("\"", "").trim();
                try {
                    String catAssociatedValue = line.substring(0, line.lastIndexOf("-")).trim();
                    catAssociatedValue = catAssociatedValue.replaceAll("\"", " ").trim();
                    if (catAssociatedValue.contains(" ")) {
                        String[] lineSplitted = catAssociatedValue.split(" ");
                        for (String tag : lineSplitted) {
                            constructString(writer, "Category", line, tag);
                            constructString(writer, "Search", line, tag);
                            lineCount += 4;
                        }
                        constructString(writer, "Category", line, catAssociatedValue);
                        constructString(writer, "Search", line, catAssociatedValue);
                        lineCount += 2;
                    } else {
                        String tag = catAssociatedValue;
                        constructString(writer, "Category", line, tag);
                        constructString(writer, "Search", line, tag);
                        lineCount += 4;
                    }
                } catch (Exception e) {
                    //errorFile.write(e.getLocalizedMessage() + "\n");
                }
            }
            System.out.println("Category line count : " + lineCount);
            //errorFile.write("Category line count : " + lineCount + "\n");
            //errorFile.flush();
        } catch (Exception e) {
            //errorFile.write(e.getLocalizedMessage() + "\n");
            //errorFile.flush();
        }
    }

    /**
     * *
     *
     * @param writer
     * @param type
     * @param catAssociatedValue
     * @param tag
     * @throws Exception
     */
    private void constructString(BufferedWriter writer, String type, String catAssociatedValue, String tag) throws Exception {
        try {
            if (tag.length() > 1) {
                if (tag.charAt(tag.length() - 1) == 's' || tag.charAt(tag.length() - 1) == 'S') {
                    writer.append(type + "," + tag + "," + catAssociatedValue + "\n");
                    writer.append(type + "," + tag.substring(0, tag.length() - 1) + "," + catAssociatedValue + "\n");
                } else {
                    if (tag.charAt(tag.length() - 1) == 'y' || tag.charAt(tag.length() - 1) == 'Y') {
                        writer.append(type + "," + tag.substring(0, tag.length() - 1) + "ies," + catAssociatedValue + "\n");
                    } else {
                        writer.append(type + "," + tag + "s," + catAssociatedValue + "\n");
                    }
                    writer.append(type + "," + tag + "," + catAssociatedValue + "\n");
                }
            } else {
                writer.append(type + "," + tag + "," + catAssociatedValue + "\n");
            }
            writer.flush();
        } catch (Exception e) {
            //errorFile.write(e.getLocalizedMessage() + "\n");
            //errorFile.flush();
        }
    }

    /**
     * *
     *
     * @param bankFile
     * @param file
     * @throws Exception
     */
    private void addDesc2Bank(FileWriter bankFile, File file) throws Exception {
        BufferedReader reader = new BufferedReader(new FileReader(file));
        BufferedWriter writer = new BufferedWriter(bankFile);
        String line = null;
        int linecount = 0;
        while ((line = reader.readLine()) != null) {
            try {
                String removedUnnecessaryData = replaceUnWantedData(line).replace(",", " ").replace("\"", "").trim();
                if (removedUnnecessaryData.contains(" ")) {
                    String[] lineSplitted = removedUnnecessaryData.split(" ");
                    for (String str : lineSplitted) {
                        tagData(writer, line, str);
                        linecount += 2;
                    }
                    tagData(writer, line, removedUnnecessaryData);
                    linecount += 2;
                } else {
                    String str = removedUnnecessaryData;
                    tagData(writer, line, str);
                    linecount += 2;
                }
            } catch (Exception e) {
                //errorFile.write(e.getLocalizedMessage());
            }
        }
        System.out.println("Description lines added : " + linecount);
        //errorFile.write("Description lines added : " + linecount + "\n");
        //errorFile.flush();
    }

    /**
     * *
     *
     * @param writer
     * @param line
     * @param str
     * @throws Exception
     */
    private void tagData(BufferedWriter writer, String line, String str) throws Exception {

        if (str != null && str.trim().length() > 0) {
            String type = getType(line);

            if (!str.equals("/") && !str.equals(".") && !str.equals("-") && !str.equals("&")) {
                if (str.charAt(str.length() - 1) == 's' || str.charAt(str.length() - 1) == 'S') {
                    writer.append(type + "," + str + "," + line + "\n");
                    writer.append(type + "," + str.substring(0, str.length() - 1) + "," + line + "\n");
                } else {
                    // Remove 'Y' char and replace with 'ies' ( ex: fly with flies ), which most of the times works for a string
                    if (str.charAt(str.length() - 1) == 'y' || str.charAt(str.length() - 1) == 'Y') {
                        writer.append(type + "," + str.substring(0, str.length() - 1) + "ies," + line + "\n");
                    } else {
                        // sometimes we have a single character in string , which we dont want to append 's' to those strings
                        if (str.length() > 1) {
                            // Somtimes we have data with '.' at the end of the string , so remnoving it and appending 's'
                            if (str.charAt(str.length() - 1) != '.' && str.charAt(str.length() - 1) != ';') {
                                writer.append(type + "," + str + "s," + line + "\n");
                            } else {
                                writer.append(type + "," + str.substring(0, str.length() - 1) + "s," + line + "\n");
                            }
                        }
                    }
                    if (str.length() == 1) {// String is a single char then Capitalize that string 
                        writer.append(type + "," + str.toUpperCase() + "," + line + "\n");
                    }
                    writer.append(type + "," + str + "," + line + "\n");
                }
            }
            writer.flush();
        }
    }

    /**
     * *
     *
     * @param line
     * @return
     */
    private String getType(String line) {
        String type = "Search";

        type = line.substring(line.lastIndexOf("-") + 1, line.length()).trim().toUpperCase();
        if (type.indexOf('\"') != -1) {
            type = line.substring(line.lastIndexOf("-") + 1, line.length() - 1).trim().toUpperCase();
        }
        System.out.println(type);
        if (types.getTypeValue(type) != null) {
            type = types.getTypeValue(type);
        } else {
            type = "Search";
        }

        return type;
    }

    /**
     * **
     *
     * @param writer
     * @param line
     * @param tag
     * @param type
     * @throws Exception
     */
    private void constructOptions(BufferedWriter writer, String line, String tag, String type) throws Exception {

        if (options.getOptionsValue(tag.toUpperCase()) != null) {
            writer.append(type + "," + options.getOptionsValue(tag.toUpperCase()) + "," + line + "\n");
            constructString(writer, "Search", line, tag.toUpperCase());
        } else {
            constructString(writer, "Search", line, tag);
        }
        writer.flush();
    }

    /**
     * **
     *
     * @param writer
     * @param line
     * @param str
     * @throws Exception
     */
    private void optionsData(BufferedWriter writer, String line, String str) throws Exception {
        if (str != null && str.trim().length() > 0) {
            String type = getType(line);
            if (str.contains("/") || str.contains("-")) {
                String[] tagSplitted = str.split("/");
                if (tagSplitted.length == 1) {
                    tagSplitted = tagSplitted[0].split("-");
                }
                for (String tag : tagSplitted) {
                    tag = removeFirstQuotes(tag);
                    constructOptions(writer, line, tag, type);
                }
                constructOptions(writer, line, str.toUpperCase(), type);
            } else {
                constructOptions(writer, line, str, type);
            }
        }
    }

    /**
     * *
     *
     * @param bankFile
     * @param file
     * @throws Exception
     */
    private void addOptions2Bank(FileWriter bankFile, File file) throws Exception {

        BufferedReader reader = new BufferedReader(new FileReader(file));
        BufferedWriter writer = new BufferedWriter(bankFile);
        String line = null;
        while ((line = reader.readLine()) != null) {
            try {
                String removedUnnecessaryData = line;
                removedUnnecessaryData = removedUnnecessaryData.replaceAll("&44;", "").replaceAll("&#044;", "").replaceAll("&#44;", "").replaceAll("&044;", "").replaceAll("_", " ").replaceAll("&8220;", "\"").replaceAll("&#8220;", "\"").replaceAll("&8221;", "\"").replaceAll("&#8221;", "\"").replaceAll("\\(", "").replaceAll("\\)", "").replaceAll("&reg;", "").replaceAll("&amp;", "").trim();

                if (removedUnnecessaryData.charAt(0) == '\"' && removedUnnecessaryData.charAt(removedUnnecessaryData.length() - 1) == '\"') {
                    removedUnnecessaryData = removedUnnecessaryData.substring(1, removedUnnecessaryData.length() - 1);
                }

                removedUnnecessaryData = removedUnnecessaryData.replaceAll("&dquote;", "\" ").replaceAll("&quot;", "\" ").trim();

                if (removedUnnecessaryData.trim().length() > 0) {
                    removedUnnecessaryData = removedUnnecessaryData.substring(0, removedUnnecessaryData.lastIndexOf("-")).trim();
                } else {
                    continue;
                }
                removedUnnecessaryData = removeFirstQuotes(removedUnnecessaryData);
                String[] words = removedUnnecessaryData.split(" ");
                removedUnnecessaryData = "";
                for (String word : words) {
                    removedUnnecessaryData += " " + removeFirstQuotes(word);
                }
                if (removedUnnecessaryData.trim().contains(" ")) {
                    String[] lineSplitted = removedUnnecessaryData.split(" ");
                    for (String str : lineSplitted) {
                        optionsData(writer, line, str.trim());
                    }
                } else {
                    String str = removedUnnecessaryData;
                    optionsData(writer, line, str.trim());
                }
            } catch (Exception e) {
                //errorFile.write(e.getLocalizedMessage() + "\n");
                //errorFile.flush();
            }
        }
    }

    /**
     * *
     * This method iterates through the ColorToAdd_AllColors.csv file and
     * appends the data to the TagBank file If the product is of multiple colors
     * then it assigns to each seperate color present in the Product Desc/Name
     *
     * @param reader
     * @param writer
     * @param type
     * @throws Exception
     */
    private void iterateMissingTagsFromFile(BufferedReader reader, BufferedWriter writer, String type) throws Exception {
        String line = null;
        ColorConstants colors = new ColorConstants();// Source for all the colors
        int lineCount = 0;
        while ((line = reader.readLine()) != null) {
            try {
                String actualAssociationWord = "";
                String associatedWord = "";
                if (line.split("\"").length > 3) {
                    actualAssociationWord = line.split(",")[1];
                } else {
                    actualAssociationWord = line.split("\"")[3].replaceAll(",", " ");
                }
                associatedWord = actualAssociationWord.substring(0, actualAssociationWord.lastIndexOf("-")).replaceAll("\"", " ").trim();
                associatedWord = replaceUnWantedData(associatedWord);

                if (associatedWord.contains("/ ")) { // some words contains / and space which we need to divide them as they are different colors
                    associatedWord = associatedWord.replaceAll("/ ", "/");
                }
                if (associatedWord.contains("_")) {
                    associatedWord = associatedWord.replaceAll("_", " ");
                }
                if (associatedWord.contains(" ")) {
                    String[] lineSplitted = associatedWord.split(" ");
                    writer.append(type + "," + associatedWord + "," + actualAssociationWord + "\n");
                    lineCount += 1;
                    for (String tag : lineSplitted) {
                        lineCount += setColorTags(writer, colors, tag, actualAssociationWord);
                    }
                } else {
                    String tag = associatedWord;
                    writer.append(type + "," + associatedWord + "," + actualAssociationWord + "\n");
                    lineCount += 1;
                    lineCount += setColorTags(writer, colors, tag, actualAssociationWord);
                }
            } catch (Exception e) {
                //errorFile.write(e.getLocalizedMessage());
            }
        }
        //errorFile.write("Number of lines for Color : " + lineCount + "\n");
        //errorFile.flush();
        System.out.println("Number of lines for Color : " + lineCount);
    }

    /**
     * *
     *
     * @param writer
     * @param colors
     * @param tag
     * @param actualAssociationWord
     * @return
     * @throws Exception
     */
    private int setColorTags(BufferedWriter writer, ColorConstants colors, String tag, String actualAssociationWord) throws Exception {
        int linecount = 0;
        try {
            if (tag.contains("/")) {
                String[] tagSplit = tag.split("/");
                if (tagSplit.length == 2) {
                    writer.append("Color Family," + "2 Tone" + "," + actualAssociationWord + "\n");
                    linecount += 1;
                }
                if (tagSplit.length > 2) {
                    writer.append("Color Family," + "Multi" + "," + actualAssociationWord + "\n");
                    linecount += 1;
                }
                for (String tagWOSlash : tagSplit) {
                    setColorFamily(writer, colors, tagWOSlash, actualAssociationWord);
                    constructString(writer, "Search", actualAssociationWord, tagWOSlash);
                    linecount += 3;
                }
            } else {
                setColorFamily(writer, colors, tag, actualAssociationWord);
                constructString(writer, "Search", actualAssociationWord, tag);
                linecount += 3;
            }
            writer.flush();
        } catch (Exception e) {
            //errorFile.write(e.getLocalizedMessage() + "\n");
            //errorFile.flush();
        }
        return linecount;
    }

    /**
     * *
     *
     * @param writer
     * @param colors
     * @param tag
     * @param actualAssociationWord
     */
    private void setColorFamily(BufferedWriter writer, ColorConstants colors, String tag, String actualAssociationWord) throws Exception {
        String colorFamily = colors.getColorFamily(tag.toUpperCase());
        try {
            if (colorFamily != null) {
                String group = "Color Family";
                if (colorFamily.equalsIgnoreCase("Prints")) {
                    group = "Pattern";
                }
                writer.append(group + "," + colorFamily + "," + actualAssociationWord + "\n");
            }
            writer.flush();
        } catch (Exception e) {
            //errorFile.write(e.getLocalizedMessage() + "\n");
            //errorFile.flush();
        }
    }

    /**
     * *
     *
     * @param bankFile
     * @param file
     * @throws Exception
     */
    private void addColors2Bank(FileWriter bankFile, File file) throws Exception {
        BufferedReader reader = new BufferedReader(new FileReader(file));
        BufferedWriter writer = new BufferedWriter(bankFile);
        String line = null;
        String type = "All Colors";
        iterateMissingTagsFromFile(reader, writer, type);
    }

    /**
     * *
     *
     * @param line
     * @return
     */
    private String replaceUnWantedData(String line) {
        line = line.replaceAll("&44;", " ").replaceAll("&#044;", " ").replaceAll("&#44;", " ").replaceAll("&044;", " ").replaceAll("_", " ").replaceAll("&8211;", "").replaceAll("&#8211;", "").replaceAll("&8220;", "\"").replaceAll("&#8220;", "\"").replaceAll("&8221;", "\"").replaceAll("&#8221;", "\"").replaceAll("\\(", "").replaceAll("\\)", "").replaceAll("&reg;", "").replaceAll("&amp;", "").trim();
        return line;
    }

    /**
     * *
     *
     * @throws Exception
     */
    public void changeTagFile() throws Exception {
        strTagOutFilePath = Util.getHelperBean().getFilePath();
        strTagOutFileDepFolder = Util.getHelperBean().getFolderPath();
        int lineCount = 0;
        String tagOutLine = null;
        String depLine = null;
        Hashtable<String, Hashtable> htProdIds = new Hashtable<String, Hashtable>();
        Hashtable<String, String> htLotIds = new Hashtable<String, String>();
        UMProgressBar pBar = new UMProgressBar();

        File tagFile = new File(strTagOutFilePath);
        BufferedReader reader = new BufferedReader(new FileReader(tagFile));

        File[] depFiles = new File(strTagOutFileDepFolder).listFiles();

        String newFileStr = tagFile.getParent() + "\\VFTemp.csv";
        File newFile = new File(newFileStr);
        BufferedWriter writer = new BufferedWriter(new FileWriter(newFile));
        Util.getLinesCount(tagFile);
        while ((tagOutLine = reader.readLine()) != null) {
            try {
                String[] csvData = tagOutLine.split(",");
                String prodId = csvData[2].substring(csvData[2].lastIndexOf("_") + 1);
                Util.getHelperBean().setCurrentCount(lineCount++);

                if (!htProdIds.containsKey(prodId)) {
                    htLotIds = new Hashtable<String, String>();
                    boolean isFirstLineWritten = false;
                    for (File depFile : depFiles) {
                        String filePath = depFile.getAbsolutePath();
                        String fileExt = filePath.substring(filePath.lastIndexOf(".") + 1);

                        if (depFile.isFile() && fileExt.equalsIgnoreCase("csv")) {
                            BufferedReader depReader = new BufferedReader(new FileReader(depFile));

                            while ((depLine = depReader.readLine()) != null) {
                                String[] csvDepData = depLine.split(",");
                                String lotId = csvDepData[5];

                                if (lotId.contains(prodId)) {
                                    if (!htLotIds.containsKey(lotId)) {
                                        htLotIds.put(lotId, csvData[2]);
                                        writer.append("Search," + lotId + "," + csvData[2] + "\n");
                                        if (!isFirstLineWritten) {
                                            writer.append(tagOutLine + "\n");
                                            isFirstLineWritten = true;
                                        }
                                        writer.flush();
                                    }
                                }
                            }
                        }
                    }
                    htProdIds.put(prodId, htLotIds);
                } else {
                    writer.append(tagOutLine + "\n");
                    writer.flush();
                }
                EventQueue.invokeLater(pBar);
            } catch (Exception e) {
                //errorFile.write(e.getLocalizedMessage() + "\n");
                //errorFile.flush();
            }
        }

        reader.close();
        writer.close();
        tagFile.delete();
        System.out.println(tagFile.getName());
        //errorFile.write(tagFile.getName() + "\n");
        //errorFile.flush();
        File nwFile = new File(tagFile.getAbsolutePath());
        System.out.println(nwFile.getAbsolutePath());
        //errorFile.write(nwFile.getAbsolutePath() + "\n");
        //errorFile.flush();
        newFile.renameTo(nwFile);

        pBar.close();
    }

    /**
     * *
     *
     * @param word
     * @return
     * @throws Exception
     */
    private String convertQuoteToInch(String word) throws Exception {
        if (word.contains("\"") && word.substring(word.length() - 1).equals("\"")) {
            String str = word.length() != 1 && word.substring(word.length() - 1).equals("\"") ? word.substring(0, word.length() - 1) : word;

            if (isInteger(str)) {
                word = str + " inches";
            }
        }
        return word;
    }

    /**
     * *
     *
     *
     * @param word
     * @return
     */
    private boolean isInteger(String word) {
        try {
            Integer.parseInt(word);
        } catch (Exception e) {
            return false;
        }
        return true;
    }

    /**
     * *
     *
     * @param line
     * @return
     * @throws Exception
     */
    private String removeFirstQuotes(String line) throws Exception {
        if (line.length() > 0) {
            line = convertQuoteToInch(line);
        }

        if (line.length() > 0 && line.substring(0, 1).equals("\"")) {
            line = line.substring(1, line.length());
        }
        if (line.length() > 0 && line.substring(line.length() - 1, line.length()).equals("\"")) {
            line = line.substring(0, line.length() - 1);
        }

        if (line.length() > 0 && (line.substring(0, 1).equals("\"") || line.substring(line.length() - 1, line.length()).equals("\""))) {
            removeFirstQuotes(line);
        }
        return line;
    }
}
